package orm

import (
	"fmt"
	"gorm.io/gorm"
	"strings"
)

func (this *QueryBuilder) CreateConditions() {
	where := this.scanConditions(this.Conditions)
	if where != nil {
		this.Tx.Where(where)
	}
}
func (this *QueryBuilder) scanConditions(conditions map[string]interface{}) *gorm.DB {
	var tx *gorm.DB
	for k, v := range conditions {
		switch k {
		case "_or", "_OR", "_Or":
			subConditions, ok := v.(map[string]interface{})
			if ok {
				if tx == nil {
					tx = this.Db.Or(this.scanConditions(subConditions))
				} else {
					tx = tx.Or(this.scanConditions(subConditions))
				}
			}
			break
		case "_ors", "_ORS", "_Ors":
			subConditions, ok := v.([]interface{})
			if ok {
				for _, condition := range subConditions {
					sunCondition, ok := condition.(map[string]interface{})
					if ok {
						if tx == nil {
							tx = this.Db.Or(this.scanConditions(sunCondition))
						} else {
							tx = tx.Or(this.scanConditions(sunCondition))
						}
					}
				}
			}
			break
		case "_and", "_AND", "_And":
			subConditions, ok := v.(map[string]interface{})
			if ok {
				if tx == nil {
					tx = this.Db.Where(this.scanConditions(subConditions))
				} else {
					tx = tx.Where(this.scanConditions(subConditions))
				}
			}
			break
		case "_not", "_Not", "_NOT":
			subConditions, ok := v.(map[string]interface{})
			if ok {
				if tx == nil {
					tx = this.Db.Not(this.scanConditions(subConditions))
				} else {
					tx = tx.Not(this.scanConditions(subConditions))
				}
			}
			break
		default:
			//todo 防止key中的sql注入尚未处理
			//检查是否包含了表达式
			fields := strings.Split(k, "__")
			if len(fields) == 2 {
				tableName, f := this.createJoin(fields[0])
				fields[0] = fmt.Sprintf("%s.%s", tableName, f)
				//识别表达式
				switch fields[1] {
				case "gt":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s > ?", fields[0]), v)
					} else {
						tx.Where(fmt.Sprintf("%s > ?", fields[0]), v)
					}
					break
				case "gte":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s >= ?", fields[0]), v)
					} else {
						tx.Where(fmt.Sprintf("%s >= ?", fields[0]), v)
					}
					break
				case "lt":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s < ?", fields[0]), v)
					} else {
						tx.Where(fmt.Sprintf("%s < ?", fields[0]), v)
					}
					break
				case "lte":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s <= ?", fields[0]), v)
					} else {
						tx.Where(fmt.Sprintf("%s <= ?", fields[0]), v)
					}
					break
				case "in":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s in ?", fields[0]), v)
					} else {
						tx.Where(fmt.Sprintf("%s in ?", fields[0]), v)
					}
					break
				case "nin":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s NOT in ?", fields[0]), v)
					} else {
						tx.Where(fmt.Sprintf("%s NOT in ?", fields[0]), v)
					}
					break
				case "sw":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s like ?", fields[0]), fmt.Sprintf("%s%%", v))
					} else {
						tx.Where(fmt.Sprintf("%s like ?", fields[0]), fmt.Sprintf("%s%%", v))
					}
					break
				case "ew":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s like ?", fields[0]), fmt.Sprintf("%%%s", v))
					} else {
						tx.Where(fmt.Sprintf("%s like ?", fields[0]), fmt.Sprintf("%%%s", v))
					}
					break
				case "like":
					if tx == nil {
						tx = this.Db.Where(fmt.Sprintf("%s like ?", fields[0]), fmt.Sprintf("%%%s%%", v))
					} else {
						tx.Where(fmt.Sprintf("%s like ?", fields[0]), fmt.Sprintf("%%%s%%", v))
					}
					break
				}
			} else {
				tableName, f := this.createJoin(k)
				if tx == nil {
					tx = this.Db.Where(fmt.Sprintf("%s.%s", tableName, f), v)
				} else {
					tx.Where(fmt.Sprintf("%s.%s", tableName, f), v)
				}
			}
		}
	}

	return tx
}
